export function SignIn() {
  // 不知道构造参数需要传几个进来。
  type ClassConstructor<T> = new (...arg: any[]) => T;

  function GetProperty<C extends ClassConstructor<any>>(Base: C) {
    return class extends Base {
      constructor(...args: any[]) {
        args.forEach((item) => {
          console.log(item);
        });
        super(...args);
      }

      static builder = class {
        private static Class: C;

        static build() {
          return this.Class;
        }
      };
    };
  }

  function Builder<C extends ClassConstructor<any>>(Base: C) {
    return class extends Base {
      constructor(...args: any[]) {
        super(...args);
        args.forEach((item) => {
          new Function(item);
        });
      }

      private static Class: C;

      static build() {
        return this.Class;
      }
    };
  }

  // @Builder
  class User {
    code: string | null = null;
    age: number | null = null;

    // constructor(public code: string, public age: number) {
    // }

    // static builder = class {
    //   private static user: User;
    //
    //   static code(code: string) {
    //     this.user.code = code;
    //     return this;
    //   }
    //
    //   static age(age: number) {
    //     this.user.age = age;
    //     return this;
    //   }
    //
    //   static build(): User {
    //     return this.user;
    //   }
    // };
  }

  const user1: User = Builder(User).build();
  console.log(user1);

  // const user = User.builder.age(18).code("123").build();
  // const test = User.builder();

  // 使用Record、Partial、Required、Readonly、Pick等属性将类型中的字段标记为可选/必填/只读，或返回只包含指定keys的子类型，而无需去构造复杂的类.
  // 慎用伴生，伴生会带来一定的困扰.
  // 使用本方法推到元组的类型，减少元组数据的类型断言
  function tuple<T extends unknown[]>(...ts: T): T {
    return ts;
  }

  // 封装类型判断, 以提高代码的可读性.
  // 使用条件类型，以满足返回值可能存在多种不同类型的情况.

  // 使用内置的条件类型，可以减少类型申明
}

export function Test() {
  let userId: Partial<string> = "";
  // let userId: string | undefined;
  fetchUser();

  if (userId !== undefined) {
    userId.toUpperCase();
  }

  function fetchUser() {
    userId = "1";
  }
}

type Exclusive<T, U> = (T extends U ? never : T) | (U extends T ? never : U);
type A = "Apple" | "AirBug" | "Another" | "Asset";
type B = "Apple" | "AirBug" | "Test" | "Mobile";
type C = Exclusive<A, B>;
const c: C = "Another";

// 实现Promise方法.
